package com.game.gateway.netty;

import com.game.gateway.config.GatewayServerConfig;
import com.game.gateway.service.NettyChannelInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelOption;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.remoting.common.RemotingUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.net.InetSocketAddress;

@Slf4j
@Service
public class ClientNettyServerBoot {
    @Resource
    private NettyChannelInitializer nettyChannelInitializer;

    @Getter
    private ServerBootstrap serverBootstrap;
    // 注入网关服务配置
    @Autowired
    protected GatewayServerConfig serverConfig;

    public void start() {
        this.init();
    }

    private void init() {
        NioEventLoopGroup bossGroup = new NioEventLoopGroup(serverConfig.getBossThreadCount());
        NioEventLoopGroup workerGroup = new NioEventLoopGroup(serverConfig.getWorkThreadCount());
        this.serverBootstrap = new ServerBootstrap();
        this.serverBootstrap.group(bossGroup, workerGroup)
					.channel(useEpoll() ? EpollServerSocketChannel.class : NioServerSocketChannel.class)
					.option(ChannelOption.SO_BACKLOG, 1024).option(ChannelOption.SO_REUSEADDR, true)
					.option(ChannelOption.SO_KEEPALIVE, false).childOption(ChannelOption.TCP_NODELAY, true)
					.childOption(ChannelOption.SO_SNDBUF, serverConfig.getSendBufSize())
					.childOption(ChannelOption.SO_RCVBUF, serverConfig.getRecBufSize())
					.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
					.localAddress(new InetSocketAddress(serverConfig.getServerPort()))
                .childHandler(this.nettyChannelInitializer);
        this.serverBootstrap.bind(serverConfig.getServerPort());
        log.info("Netty started on port: {} (TCP) with boss thread count{}", serverConfig.getServerPort(), serverConfig.getBossThreadCount());
    }

    private boolean useEpoll() {
        return RemotingUtil.isLinuxPlatform() && Epoll.isAvailable();
    }
}

